Now Loading ...
-
[ML] VIME: Extending the Success of Self- and Semi-supervised Learning to Tabular Domain
논문 정보
제목: VIME: Extending the Success of Self- and Semi-supervised Learning to Tabular Domain
링크: NeurIPS 2020
이미지·자연어에서 자기지도(self-supervised)·준지도(semi-supervised) 학습은 적은 라벨로도 뛰어난 성능을 내는 핵심 기술이 되었다. 하지만 이 기법들은 이미지의 공간적 구조(spatial structure)나 언어의 의미적 구조(semantic structure)에 강하게 의존하며, 이러한 과제는 표 형태의 정형 데이터(tabular data)에는 그대로 옮길 수 없다.
VIME(Value Imputation and Mask Estimation, 값 대체 및 마스크 추정)은 이 차이를 메우기 위해, tabular 데이터에 맞는 새로운 자기지도 과제와 새로운 준지도 데이터 증강법을 함께 제안한다.
1. 핵심 용어
1.1 Semi-supervised learning (준지도 학습)
지도 학습과 자기지도 학습의 중간에 있는 방식이다.
지도 학습은 라벨링이 되어 있는 데이터를 사용하는데, 보통 이러한 데이터의 양은 매우 적다. 이렇게 적은 데이터뿐이면 모델이 그 소수 샘플에 overfit되기 쉽다. 준지도 학습은 여기에 라벨 없는 대량의 데이터까지 함께 활용해서 이 문제를 완화한다.
핵심 직관은 “라벨은 없어도, 입력 데이터 $x$의 분포 자체가 정보를 준다”는 것이다. 준지도 학습은 크게 두 갈래로 볼 수 있다.
Entropy minimization(엔트로피 최소화): 라벨이 없는 데이터에 대해 모델이 자신 있게(예측하는 p가 클수록 엔트로피가 줄어듦) 예측하도록 유도.
Consistency regularization(일관성 정칙화): “데이터에 변형을 가해서 새로운 input을 만들었을 때에도 예측 결과는 그대로여야 한다”는 가정을 바탕으로 모델을 regularize하는 방법
VIME의 뒷쪽 부분이 준지도 학습이며, 이때 앞쪽에서 학습한 인코더를 재사용한다.
1.2 Pretext task (사전 과제) & Downstream task
자기지도 학습에서 “진짜 풀고 싶은 과제 대신, 표현을 학습시키려고 일부러 만들어 푸는 과제”이다. 말 그대로 표현 학습을 위한 “구실용 과제”이다.
이미지의 pretext task 예: 회전 각도 맞히기, 직소 퍼즐 맞추기, 흑백 이미지에 색 입히기
언어의 pretext task 예(BERT): 가려진 단어 맞히기, 다음 문장 예측
이 과제들의 정답은 데이터에서 생성된 것이므로 내재되어 있다. 중요한 건 이 가짜 과제를 잘 풀려면 데이터의 본질을 이해해야 하도록 설계하는 것으로, 그 과정에서 인코더가 쓸모 있는 표현을 배우게 된다. VIME의 핵심 기여가 바로 tabular데이터에 맞는 새로운 pretext task를 제안한 것이다.
pretext task로 표현을 배운 뒤, 실제로 풀고 싶은 진짜 과제(예: 질병 예측, 소득 분류)를 downstream task라고 한다. “상류(pretext)에서 배운 걸 하류(downstream)에서 쓴다”는 흐름의 비유.
1.3 Encoder
인코더 $e: \mathcal{X} \to \mathcal{Z}$ 는 입력 $x$를 받아 표현 $z = e(x)$ 를 뽑아내는 신경망이다. VIME에서 자기지도 학습이 끝나고도 계속 재사용되는 부분이다. 나머지 추정기들은 표현을 잘 배우게 하기 위한 보조 장치이고, 학습이 끝나면 버린다.
1.4 Mask vector & Value imputation (마스크 벡터와 값 대체)
Mask vector(마스크 벡터) $\mathbf{m}$: 어떤 특징을 오염시킬지 표시하는 0/1 벡터이다. $m_j = 1$이면 $j$번째 특징을 오염(교체), $m_j = 0$이면 원본 유지.
Value imputation(값 대체): 오염하기로 한 자리에 새 값을 채워 넣는 것. 원래 “imputation”은 통계학에서 결측값을 그럴듯한 값으로 메우는 것을 뜻하기도 한다.
2. VIME의 원리
VIME은 자기지도 학습(1단계) 으로 좋은 인코더를 먼저 만든 뒤, 그 인코더를 준지도 학습(2단계) 에 재사용한다.
2.1 오염 샘플 만들기 (Value Imputation)
각 특징 자리마다 성공 확률이 $p_m$인 베르누이 시행(Bernoulli trial)을 한 번씩, 총 $d$번 진행한다.
\[\mathbf{m} = [m_1, \dots, m_d]^\top \in \{0,1\}^d\]
그다음 마스크가 1인 자리는 오염값 $\bar{x}$로, 0인 자리는 원본 $x$로 채워 오염 샘플 $\tilde{x}$를 만듭니다($\odot$는 원소별 곱).
\[\tilde{\mathbf{x}} = g_m(\mathbf{x}, \mathbf{m}) = \mathbf{m} \odot \bar{\mathbf{x}} + (1 - \mathbf{m}) \odot \mathbf{x}\]
여기서 오염값 $\bar{x}_j$는 그 열 $j$의 경험적 주변 분포 $\hat{p}_{X_j}$에서 뽑는다. –> $\tilde{x}$는 여전히 “실제 데이터처럼 생긴, 그럴듯한” 샘플이 된다.
2.2 두 개의 pretext task
오염된 $\tilde{x}$를 인코더가 출력한 표현 $z = e(\tilde{x})$를 받아 두 개의 추정기가 각자 과제를 푼다.
1. Mask vector estimation(마스크 벡터 추정): VIME의 새로운 pretext task. 추정기 $s_m: \mathcal{Z} \to [0,1]^d$ 가 어느 자리가 오염되었는지를 예측한다. 즉 마스크 $\mathbf{m}$을 복원한다.
2. Feature vector estimation(특징 벡터 추정): 기존 오토인코더식 복원 과제. 추정기 $s_r: \mathcal{Z} \to \mathcal{X}$ 가 오염되기 전 원본 값은 무엇이었는지 예측. 즉 원본 $\mathbf{x}$를 복원하려고 한다.
두 추정기와 인코더를 함께 학습시킨다.
\[\min_{e,\, s_m,\, s_r} \;\;
\mathbb{E}_{\mathbf{x} \sim p_X,\; \mathbf{m} \sim p_m,\; \tilde{\mathbf{x}} \sim g_m(\mathbf{x},\mathbf{m})}
\Big[\, l_m(\mathbf{m}, \hat{\mathbf{m}}) + \alpha \cdot l_r(\mathbf{x}, \hat{\mathbf{x}}) \,\Big]\]
여기서 $\hat{\mathbf{m}} = (s_m \circ e)(\tilde{\mathbf{x}})$, $\hat{\mathbf{x}} = (s_r \circ e)(\tilde{\mathbf{x}})$ 이며, $\alpha$는 두 손실의 균형을 맞추는 하이퍼파라미터이다.
마스크 추정 손실 $l_m$ 은 mask vector 각 차원에 대한 binary cross-entropy의 평균이다.
\[l_m(\mathbf{m}, \hat{\mathbf{m}}) = -\frac{1}{d}\sum_{j=1}^{d}
\Big[\, m_j \log \hat{m}_j + (1 - m_j)\log\!\left(1 - \hat{m}_j\right) \Big]\]
복원 손실 $l_r$은 연속형 특징에 대한 MSE이다. (범주형 특징은 cross-entropy loss로 대체함.)
\[l_r(\mathbf{x}, \hat{\mathbf{x}}) = \frac{1}{d}\sum_{j=1}^{d}\left(x_j - \hat{x}_j\right)^2\]
2.3 인코더는 무엇을 배우는가?
두 과제를 잘 풀려면 인코더는 반드시 특징들 사이의 상관관계(correlation) 를 포착해야 한다.
$s_m$(마스크 추정): 어떤 특징 값이 주변의 상관된 특징들과 어긋나 있으면, 그 자리는 오염됐을 가능성이 높다고 판단할 수 있다.
$s_r$(복원): 오염되지 않고 남아 있는 상관된 특징들로부터 오염된 자리의 원래 값을 추론.
즉 두 과제 모두 “특징 간 상관 구조를 알아야” 풀리도록 설계되어, 인코더가 그 구조를 표현 $z$에 담게 된다. 이미지의 공간적 상관, 언어의 앞뒤 단어 상관을 배우는 것과 같은 원리를, 상관 구조가 명시적이지 않은 표 데이터에 이식한 것이 VIME의 핵심이다.
2.4 준지도 학습
이제 학습된 인코더 $e$를 freeze 하고, 그 위에 예측기 $f$를 추가한다.
$f_e = f \circ e$, $\hat{y} = f_e(x)$ 로 두며, 최종 목적함수는 지도 손실과 비지도 손실의 합이다.
\[\mathcal{L}_{\text{final}} = \mathcal{L}_s + \beta \cdot \mathcal{L}_u\]
지도 손실 $\mathcal{L}_s$: 라벨 있는 데이터로 계산하는 표준 손실. (mean squared error for regression or categorical cross-entropy for classification)
\[\mathcal{L}_s = \mathbb{E}_{(x,y)\sim p_{XY}}\big[\, l_s(y,\, f_e(x)) \,\big]\]
비지도(일관성) 손실 $\mathcal{L}_u$: 라벨 없는 데이터로 계산. 같은 샘플 $x$와, 그것을 오염시킨 $\tilde{x}$에 대한 예측이 비슷해지도록 강제하는 것이다. (Consistency regularization)
\[\mathcal{L}_u = \mathbb{E}_{x \sim p_X,\; m \sim p_m,\; \tilde{x} \sim g_m(x,m)}
\Big[\, \big\lVert f_e(\tilde{x}) - f_e(x) \big\rVert^2 \,\Big]\]
$\mathcal{L}_u$가 강제하는 규칙은 “같은 데이터를 조금 오염시켜도, 모델의 예측은 흔들리면 안된다.”는 것이다.
수식을 다시 보면 두 예측의 차이를 제곱해서, 이걸 0에 가깝게(= 두 예측이 같게) 만들라는 것이다.
\[\mathcal{L}_u = \mathbb{E}\Big[\, \big\lVert \underbrace{f_e(\tilde{x})}_{\text{오염본 예측}} - \underbrace{f_e(x)}_{\text{원본 예측}} \big\rVert^2 \,\Big]\]
데이터의 오염은 무작위로 진행된다. 그래서 오염본을 딱 1개만 만들면, 극단적인 오염이 걸리거나 원본과 거의 같게 되는 경우가 생길 수 있다.
그래서 실제로는 한 샘플 $x$마다 오염본을 $K$개 만들어($\tilde{x}_1, \dots, \tilde{x}_K$) 그 예측들의 흩어짐을 평균을 낸다. “이 샘플을 여러 방식으로 흔들어봤을 때, 예측이 얼마나 널뛰나(분산)” 를 재는 것이고, 그 널뜀을 줄이라는 것이다.
\[\hat{\mathcal{L}}_u = \frac{1}{N_b K}\sum_{i=1}^{N_b}\sum_{k=1}^{K}
\big\lVert f(z_{i,k}) - f(z_i) \big\rVert^2\]
여기서 $N_b$는 배치 크기, $z_{i,k} = e(\tilde{x}_{i,k})$, $z_i = e(x_i)$ 이다. 내부합 $\sum_k$가 예측들의 평균, 외부합 $\sum_i$가 배치 내 샘플들에 대한 평균이다.
또한 이 일관성 손실의 “변형(오염)”은 1단계 자기지도 학습으로 얻은 인코더를 통과한 오염이다.
1단계: 오염을 만들어 “어디가 오염됐나 / 원본이 뭐였나”를 풀며 인코더를 학습
2단계: 똑같은 오염 방식을 이번엔 “흔들어도 예측이 같아야 한다”는 일관성 신호로 재사용
같은 오염 도구를 두 단계에서 다른 목적으로 두 번 사용하는 구조이다.
3. 실험 결과
Genomics data: VIME이 지도(ElasticNet)·자기지도(Context Encoder)·준지도(MixUp) 모두를 앞섰고, 많은 경우 라벨을 절반만 쓰고도 다른 기법과 비슷한 성능을 보임.
Clinical data: 두 가지 치료 예측(호르몬 요법/근치 요법)에서 VIME이 최고 AUROC를 기록.
Public tabular data: 라벨 10% / 비라벨 90% 세팅에서 VIME이 도메인에 관계없이 최고 정확도를 보임.
4. SCARF와의 비교
SCARF 설명 글
항목
VIME
SCARF
자기지도 손실
복원 + 마스크 추정
대조 학습 (InfoNCE)
pretext task
“어디가 오염됐나 + 원본이 뭐였나” 복원
“같은 원본에서 나온 두 view 짝짓기”
오염 방식
각 열의 경험적 주변 분포에서 교체 (동일)
각 열의 경험적 주변 분포에서 교체 (동일)
미세조정 범위
인코더 고정, 예측기만 학습
인코더 포함 전체 미세조정
준지도 요소
있음 (일관성 손실 $\mathcal{L}_u$)
없음 (순수 사전학습→미세조정)
핵심 차이는 “오염을 어떻게 활용하느냐” 이다. VIME은 오염을 복원, 마스크 추정 과제의 재료로 쓰고, SCARF는 같은 오염을 대조 학습의 view 생성에 사용한다. SCARF 논문은 이 대조 방식이 VIME의 복원 방식보다 효과적이라고 보고했다.
-
[ML] SCARF: Self-Supervised Contrastive Learning using Random Feature Corruption
논문 정보
제목: SCARF: Self-Supervised Contrastive Learning using Random Feature Corruption
arXiv: 2106.15147
비전(SimCLR)이나 NLP(BERT, GPT-3)에서는 self-supervised pretraining이 크게 성공했는데, 그 핵심은 도메인에 맞는 “view 생성 방법”이었다(비전의 crop/color distortion, NLP의 token masking). 그런데 정작 현실에서 가장 흔한 데이터 형태인 테이블 형태 데이터(tabular data) 에서는 이런 기법이 거의 활용되지 못하고 있었다. 이미지의 “자르기(crop)”, NLP의 “토큰 마스킹(token masking)” 같은 데이터 변형 기법들이 전부 도메인 특화(domain-specific) 라서, 열(column)마다 의미가 제각각인 표 데이터에는 그대로 쓸 수 없기 때문이다.
SCARF는 이 문제를 아주 단순한 아이디어로 해결한다. 입력 특징(feature) 중 일부를 무작위로 골라, 그 값을 “그 열에 실제로 등장했던 다른 값”으로 바꿔치기하는 것이다.
1. 핵심 용어
1.1 Self-supervised learning (자기지도 학습)
Supervised learning(지도 학습) 은 (입력, 정답 라벨) 쌍으로 학습한다. 문제는 label이 있는 데이터는 사람이 일일이 붙여야 하므로 비용이 들고, 양도 적은 경우가 있다. 반면 라벨이 없는 데이터는 세상에 넘쳐난다.
Self-supervised learning은 이 라벨 없는 “데이터 자체로부터 문제를 스스로 만들어” 학습하는 방식이다. “self(스스로) + supervised(지도)”라는 이름 그대로, 정답을 사람이 주는 게 아니라 데이터 구조에서 자동으로 만들어낸다.
BERT: 문장에서 단어를 일부 가리고 “가려진 단어를 맞혀라”는 문제를 스스로 출제 → 정답은 원래 그 자리에 있던 단어
SimCLR: 같은 이미지를 두 가지로 변형시킨 후 같은 이미지에서 나왔는지 판단
이렇게 학습하면 “고양이 vs 개” 같은 특정 과제와 무관하게, 입력 데이터의 일반적이고 유용한 표현(representation)자체를 학습하게 된다.
1.2 Pretraining & Fine-tuning (사전학습과 미세조정)
자기지도 학습은 보통 두 단계로 진행된다.
Pretraining(사전학습): 라벨 없는 대량의 데이터로 위에서 말한 self-supervised 방식으로 인코더(encoder) 를 먼저 훈련시킨다. 이 단계의 목표는 정확한 분류가 아니라 “좋은 표현을 뽑아내는 능력”을 갖추는 것이다.
Fine-tuning(미세조정): 사전학습된 인코더 위에 분류기(classification head) 를 얹고, 이번엔 라벨이 있는 (적은) 데이터로 실제 과제(예: 분류)에 맞게 전체를 조금 더 학습시킨다.
핵심은 사전학습이 좋은 출발점(초기 가중치)을 만들어주기 때문에, 미세조정 단계에서 라벨이 적어도 높은 성능이 나온다는 것이다. SCARF는 이 전형적인 구도를 따른다.
참고로 SCARF는 미세조정 단계에서 인코더 f까지 전부 다시 학습시킨다. (VIME은 인코더를 얼려두고 분류기만 학습한다는 점이 다르다.)
1.3 Representation & Embedding (표현, 임베딩)
신경망이 입력을 통과시키면서 만들어내는 중간 벡터 표현을 representation 또는 embedding이라고 부른다. 예를 들어 128차원 입력이 인코더를 지나 256차원 벡터가 되었다면, 그 256차원 벡터가 이 입력의 “표현”이다. 좋은 표현이란 비슷한 입력끼리는 가깝고, 다른 입력끼리는 먼 벡터 공간을 만드는 것을 뜻한다.
1.4 View (뷰)
이 논문의 핵심 개념이다. View란 “같은 원본 데이터를 살짝 다르게 변형한 버전” 을 말한다.
이미지에서의 view: 같은 사진을 무작위로 자르거나(crop), 색을 왜곡하거나(color distortion), 흐리게(blur) 만든 이미지
NLP에서의 view: 같은 문장에서 일부 토큰을 마스킹한 데이터
SCARF에서의 view: 같은 행(row) 데이터에서 일부 특징(feature)을 무작위로 오염시킨 데이터
“같은 원본에서 나온 두 view는 서로 가깝게, 다른 원본에서 나온 view들은 서로 멀게” 만들도록 학습하면, 신경망은 표면적인 변형에 흔들리지 않고 본질적인 표현을 배우게 된다. 즉 view는 어떤 변형에도 불변인(invariant) 특징을 배우도록 하기 위해 사용하는 것이다.
1.5 Contrastive learning (대조 학습)
위에서 설명한 같은 것끼리 가깝게 하고, 다른 것끼리 멀게 만들도록 학습시키는 것을 contrastive(대조) learning이라고 합니다.
Positive pair(양성 쌍): 같은 원본에서 나온 두 view. → 가깝게 만들어야 함
Negative pair(음성 쌍): 서로 다른 원본에서 나온 view들. → 멀게 만들어야 함
이를 하나의 수식(손실 함수)으로 표현한 것이 InfoNCE이다.
1.6 InfoNCE
“Information Noise Contrastive Estimation”의 줄임말로, 대조 학습에서 가장 널리 쓰이는 손실 함수(loss function)이다.
이 손실을 최소화하는 것은 두 view가 공유하는 정보의 양, 즉 상호 정보량(mutual information)을 최대화하는 것과 같다. 두 view의 공유 정보란 “오염에도 살아남은 본질적인 정보”이므로, 이를 최대화한다는 건 노이즈에 흔들리지 않고 데이터의 핵심을 담는 표현을 학습한다는 뜻이다. (손실 ↓ = 상호 정보량 ↑)
수식을 뜯어보면 사실 “소프트맥스 분류(softmax classification)” 와 똑같은 구조이다. SCARF의 손실 수식은 다음과 같다.
\[\mathcal{L} = -\frac{1}{N} \sum_{i=1}^{N} \log
\frac{\exp\!\left(s_{i,i}/\tau\right)}
{\dfrac{1}{N}\displaystyle\sum_{k=1}^{N} \exp\!\left(s_{i,k}/\tau\right)}\]
배치(batch) 안에 N개의 원본이 있고, 각 원본 i마다 원본 view $z^{(i)}$ 와 오염된 view $\tilde{z}^{(j)}$ 두 개가 있다고 하면,
$s_{i,j}$ : $z^{(i)}$ 와 오염 view $\tilde{z}^{(j)}$ 사이의 코사인 유사도이다. 두 벡터를 각자 길이로 나눠 정규화한 뒤 내적한 값으로, 방향이 얼마나 비슷한지를 -1 ~ 1로 나타낸다.
$s_{i,k}$ 에서 i=k인 경우 같은 원본에서 나온 positive pair의 유사도이므로 최대화 해야하는 값이고, k≠i인 경우 다른 원본과의 negative pair 유사도이므로 최소화하도록 한다.
τ (temperature, 온도): 표현의 스케일을 조절하는 값이다. 작을수록 가장 큰 유사도에 극단적으로 집중하고, 클수록 완만해진다. SCARF는 기본값으로 τ = 1을 사용(즉 그냥 순수 소프트맥스).
분자 $\exp\left(s_{i,i}/\tau\right)$ 는 positive pair의 유사도 점수이고, 분모는 이를 포함하여 배치 전체 view와의 유사도 점수를 총합한 것이다. (분모에서 i는 고정이고 k만 변함)
이 분수는 “배치 안의 N개의 후보 중에서 자신의 진짜 짝(positive)을 골라낼 확률이다. 이 확률을 1에 가깝게 하는 것이 목표이므로, 즉 -log 값을 0에 가깝게 최소화하는 것이 학습 목표이다.(진짜 짝과의 유사도(s_ii)를 키우고 나머지(s_ik)를 줄이도록)
배치사이즈가 N이면 문제는 “1개의 positive와 N−1개의 negative 중 고르기”가 되는데, 배치가 클수록 negative가 많아져 문제가 어려워지고, 보통 어려운 문제가 표현을 더 잘 학습시킨다. (다만 뒤에서 보듯 SCARF는 배치 크기에 크게 민감하지 않다.)
1.7 Empirical marginal distribution (경험적 주변 분포)
Marginal distribution(주변 분포): 여러 변수 중 딱 하나의 변수만 떼어놓고 본 값의 분포이다. 표 데이터로 치면 “특정 한 열(column)”에 있는 값들의 분포.
Empirical(경험적): 이론적 수식이 아니라 실제 데이터에 등장한 값들로 만든 분포라는 뜻.
즉 어떤 열의 empirical marginal distribution이란 “학습 데이터에서 그 열이 실제로 가졌던 값들의 집합” 이고, 등장한 빈도를 그대로 반영한 분포이다. SCARF는 여기서 균등하게(uniformly) 하나를 뽑아 오염에 사용한다.
“uniform”은 “N개의 행을 각각 1/N 확률로 똑같이 뽑는다” 는 뜻이지, “회사원·학생·자영업·무직 네 종류가 나왔을때 각각을 1/4로 뽑는다”는 뜻이 아니다. 등장한 빈도를 반영하여 뽑는다.
2. SCARF의 원리
SCARF는 네트워크를 3가지로 분해하며 각각 256 은닉차원을 가지는 ReLU 네트워크이다. $f$는 4 layers, 나머지 $g$와 $h$는 2 layers이다.
$f$(encoder): 입력에서 표현을 뽑는 본체. 최종적으로 우리가 재사용하고 싶은 건 오직 이 인코더 $f$이다.
$g$(pre-train head): 대조 학습 전용 보조 신경망. 출력을 L2 정규화하여 벡터들이 반지름 1인 초구(unit hypersphere) 위에 놓이게 만든다. 이 정규화가 실무적으로 매우 중요하다고 알려져 있다. 사전학습이 끝나면 $g$는 버려진다.
$h$(classification head): 미세조정 단계에서 $f$의 출력을 받아 레이블을 예측하는 분류기.
view를 어떻게 만드는가
미니배치의 각 샘플 $x^{(i)}$ 에 대해:
오염할 특징 개수 결정. 전체 특징 수가 $M$ 이고 오염률(corruption rate) $c$ 가 $0.6$ 이면, $q = \lfloor c \cdot M \rfloor$ 개, 즉 약 60%의 특징을 오염시키기로 설정.
오염할 위치 무작위 선택. ${1, \dots, M}$ 에서 크기 $q$ 인 부분집합 $I_i$ 를 균등 무작위로 뽑는다. 샘플마다, 매 스텝마다 다른 위치를 뽑는다.
선택된 특징을 오염. 오염 대상으로 뽑힌 위치 $j$ 의 값은, 그 열 $j$ 의 empirical marginal distribution $\hat{X}_{c_j}$ 에서 새로 뽑은 값 $v$ 로 교체한다. 뽑히지 않은 위치는 원본 값 그대로 유지.
\[\tilde{x}^{(i)}_j =
\begin{cases}
x^{(i)}_j & \text{if } j \notin I_i \quad \\
v, \quad v \sim \hat{X}_{c_j} & \text{if } j \in I_i \quad
\end{cases}\]
구체적인 예시로, 한 사람의 데이터가 이렇게 있다.
나이
소득
직업
지역
자녀수
34
5200
회사원
서울
2
여기서 ‘소득’과 ‘직업’이 오염 대상으로 뽑혔다면, 각 열이 데이터셋에서 실제로 가졌던 값 중 무작위로 하나씩 뽑아 교체한다.
나이
소득
직업
지역
자녀수
34
5200 3100
회사원 학생
서울
2
이렇게 만들어진 오염본이 바로 원본의 view이고, (원본, 오염본)이 하나의 positive pair가 된다.
이렇게 “그 열의 실제 값으로” 교체 하면 원래 그 열의 “단위”와 분포를 그대로 유지하여 좋다. 따로 하이퍼파라미터를 만들 필요도 없고, 특징 스케일링 방식(z-score, min-max 등)에 불변(invariant) 하다.
손실 계산과 최적화
앞서 만든 두 view를 각각 $f \to g$ 에 통과시켜 임베딩 $z^{(i)}$, $\tilde{z}^{(i)}$ 를 얻고, InfoNCE loss를 계산한다. 여기서 $z^{(i)} = g\bigl(f(x^{(i)})\bigr)$, $\tilde{z}^{(i)} = g\bigl(f(\tilde{x}^{(i)})\bigr)$ 이다.
모든 $i$ 에 대해 $z^{(i)}$ 와 $\tilde{z}^{(i)}$ (같은 원본) → 가깝게, 즉 $s_{i,i}$ 를 크게
$i \neq j$ 인 $z^{(i)}$ 와 $\tilde{z}^{(j)}$ (다른 원본) → 멀게, 즉 $s_{i,j}$ 를 작게
$f$, $g$ 의 파라미터는 경사하강(SGD) 방식으로 갱신한다. 실제 모든 실험에서 사용한 구체적인 옵티마이저는 Adam(학습률 $0.001$, 배치 크기 $128$)이다.
사전학습을 몇 epoch 돌려야 하는지는 데이터셋마다 다르기에, 검증 데이터에 대한 InfoNCE loss를 이용해 early stopping을 할 수도 있다. 라벨 없는 검증 데이터로 $(x^{(i)}, \tilde{x}^{(i)})$ 쌍을 미리 한 번 만들어 고정된 정적 검증셋을 만들고, 학습 내내 이 검증 셋의 손실을 추적한다.
학습 손실 곡선은 매 스텝 무작위 오염 때문에 noisy 하지만, 검증 손실 곡선은 검증셋을 한 번 만들어 고정하므로 매끄럽다. 또 조기 종료 기준으로 InfoNCE “손실”을 쓰는 게 InfoNCE “에러(오분류율)”를 쓰는 것보다 성능이 좋았다.
3. 실험
데이터셋: OpenML-CC18 벤치마크의 실제 분류 데이터셋 69개(원래 72개에서 이미지 데이터인 MNIST, Fashion-MNIST, CIFAR-10 제외). 각 데이터셋을 70%/10%/20%로 train/validation/test 분할하고, 30번씩 반복 실험.
세 가지 시나리오에서 사전학습이 테스트 정확도를 얼마나 올리는지 측정하였다.
전체 라벨(fully-supervised): 라벨을 100% 사용.
준지도(semi-supervised): 라벨을 25%만 주고 나머지 75%는 라벨 없이.
라벨 노이즈(label noise): 학습 라벨의 30%를 무작위 클래스로 오염.
세 상황 모두에서 SCARF가 도움이 되었다.
먼저 라벨이 완벽하게 다 주어진 상황에서 SCARF는 기존 기법들(mixup·label smoothing·dropout·distillation) 위에 얹었을 때 약 1~2%의 상대적 향상을 더했다.
라벨이 25%뿐인 준지도 상황에서 효과가 가장 극적이었으며, 다른 준지도 전용 기법 위에서도 2~4% 향상되었다.
라벨의 30%가 무작위로 틀어진 노이즈 상황에서는 향상 폭이 2~3%.
핵심은 “SCARF가 기존 기법을 대체하는 게 아니라 보완한다(complements)” 는 사실이다. 만약 SCARF가 mixup이나 dropout과 똑같은 원리로 작동한다면, 이미 그 기법들을 쓰고 있는 모델에 SCARF를 더 얹어봐야 효과가 겹쳐서 추가 이득이 없을텐데, 잘 튜닝된 기법들 위에 얹어도 여전히 성능이 오른다는 건 그것들과 다른 메커니즘, 데이터 구조에서 표현을 학습하는 방식으로 작동한다는 증거이다. 실용적으로, 지금 쓰는 파이프라인을 갈아엎지 않고 위에 한 겹만 더 얹으면 된다는 뜻이라 매력적이다.
저자들이 언급한 한계: 입력 데이터에 존재하는 편향(bias)을 표현이 그대로 학습·강화할 수 있으며, 이를 완화하는 방법은 향후 과제로 남김
비교에 사용된 주요 baseline들
종류
방법
범용(정확도·노이즈·distill)
Label smoothing, Dropout, Mixup, Self-distillation
사전학습(핵심 비교군)
Autoencoder 3종(no-noise / additive-noise / SCARF-corruption AE), Discriminative SCARF
라벨 노이즈 전용
Deep k-NN, Bi-tempered loss
준지도 전용
Self-training, Tri-training
실무 참고
XGBoost (부록의 절대 정확도 비교)
4. Ablation Study
논문은 SCARF의 각 설계 선택이 정말 필요한지 꼼꼼히 실험하였다. (Ablation은 “구성 요소를 하나씩 제거/변경해 그 기여도를 측정하는” 실험을 말함)
Marginal 샘플링이 다른 오염 방식보다 우수하다: 다른 대안(오염 없음, 평균값으로 교체, 노이즈 추가, joint(행 전체를 다른 샘플에서 통째로 가져오기), 0으로 만들기(feature dropout))보다 SCARF의 marginal 방식이 여러 스케일링 하에서 가장 견고했음.
배치 크기에 둔감하다: SimCLR 등은 배치를 5000까지 키워야 좋아지지만, SCARF는 128을 넘겨도 유의미한 개선이 없었다. 대규모 배치를 위한 엔지니어링 부담이 적다.
오염률 c는 50~80% 구간에서 성능이 안정적이라 기본값 0.6을 권장함. 온도 τ도 마찬가지로 안정적이며 기본값 1(순수 소프트맥스)을 권장.
오염 세부 튜닝: 부록에 따르면 인코더에 들어가는 두 view를 모두 오염시키는 것보다 한쪽 view만 오염시키는 게 낫고(양쪽을 60%씩 오염하면 두 view가 공유하는 정보가 너무 적어 문제가 지나치게 어려워짐), 배치 내 샘플마다 다른 위치를 오염시키는 게 같은 위치를 쓰는 것보다 낫다.
-
[ML] Revisiting Deep Learning Models for Tabular Data
논문 정보
제목: Revisiting Deep Learning Models for Tabular Data
arXiv: 2106.11959
코드: yandex-research/rtdl-revisiting-models
1. Introduction
이미지, 오디오, 텍스트에서의 성공 이후로, 테이블(정형) 데이터에도 딥러닝을 적용하려는 시도가 늘고 있다.
잠재적으로 GBDT보다 높은 성능을 낼수도 있고, 입력의 일부만 테이블이고 나머지는 이미지/오디오인 멀티모달 파이프라인을 gradient 기반으로 end-to-end 학습할 수 있다는 점에서 DL 아키텍쳐는 정형 데이터에서도 매력적일 수 있다.
하지만, 이 분야에 ImageNet(CV)이나 GLUE(NLP) 같은 확립된 벤치마크가 없어 논문마다 서로 다른 데이터셋을 쓰며 제안된 모델들이 서로 제대로 비교되지 않는다.
그래서 “어떤 DL 모델이 일반적으로 더 좋은가”, “딥러닝이 GBDT를 넘어섰는가”에 대한 답이 불분명하다.
적당한 노력으로 여러 태스크에서 안정적인 성능을 내는 신뢰할 만한 베이스라인이 부족하다. MLP가 그 역할을 해왔지만, 다른 모델들에 비해 성능이 충분하지 않음.
이 논문이 정리한 네 가지 기여(Contribution)는 다음과 같다.
Tabular 데이터용 주요 DL 모델들을 다양한 task에서 공정하게 평가하여 상대적 성능을 조사.
ResNet 계열 아키텍처가 효과적인 베이스라인임을 보임.
Transformer를 정형 데이터에 각색한 FT-Transformer를 제안. 대부분의 태스크에서 최고 성능을 보이며, 다른 DL 모델보다 넓은 범위의 태스크에서 잘 작동하는 “보편적(universal)” 아키텍처임을 확인한다.
GBDT와 딥러닝 모델 사이에 아직 보편적 승자는 없다.
2. Related Work
딥러닝을 제외한, 전통적인(=shallow) 머신러닝 방법들 중에서는 GBDT가 정형 데이터의 최고 성능(SOTA) 자리를 차지하고 있다(XGBoost, LightGBM, CatBoost). 이들은 구현 디테일이 달라도 대부분의 태스크에서 성능 차이가 크지 않다.
한편 최근 제안된 딥러닝 모델들은 대략 세 갈래로 나눌 수 있다.
(1) Differentiable Trees (미분 가능한 트리)
결정 트리 앙상블의 강력함에서 출발한 계열. 결정 트리는 미분 불가능해서 end-to-end 학습을 할 수 없으므로, 내부 노드의 결정 함수를 smooth하여 트리 함수와 라우팅을 미분 가능하게 만든다(NODE 등). 일부 태스크에서 GBDT를 이기기도 하지만, 이 논문 실험에서는 ResNet을 일관되게 이기지 못했다.
(2) Attention-based Models (어텐션 기반)
어텐션 모듈을 tabular 데이터에 도입한 계열(TabNet, AutoInt 등). 하지만 실험 결과, 잘 튜닝한 ResNet이 기존 어텐션 기반 모델들을 능가했다. 그럼에도 저자들은 Transformer를 정형 데이터에 제대로 적용하는 방법을 찾아냈고, 그 결과가 FT-Transformer다.
(3) 곱셈적 상호작용의 명시적 모델링
추천 시스템·CTR 예측 문헌에서 MLP가 feature 간 곱셈적 상호작용을 잘 모델링하지 못한다는 비판이 있었다. 이에 feature product를 MLP에 넣는 방법들이 제안됐다(DCN V2 등). 하지만 이 논문에서는 잘 튜닝한 베이스라인보다 우월하지 않았다.
3. Models for tabular data problems
Notation
데이터셋 $D = {(x_i, y_i)}_{i=1}^n$
각 객체 $x_i = (x_i^{(num)}, x_i^{(cat)})$ — 수치형·범주형 feature
feature 총 개수 $k$
$D = D_{train} \cup D_{val} \cup D_{test}$ (val은 early stopping과 hyperparams튜닝, test는 최종 평가에만 사용)
이진 분류 $Y={0,1}$, 다중 분류 $Y={1,\dots,C}$, 회귀 $Y=\mathbb{R}$ 에 대해서 진행
3.1 MLP
\(\text{MLP}(x) = \text{Linear}(\text{MLPBlock}(\dots(\text{MLPBlock}(x))))\)
\(\text{MLPBlock}(x) = \text{Dropout}(\text{ReLU}(\text{Linear}(x)))\)
3.2 ResNet
ResNet이 입력에서 출력까지 명확한 경로(clear main path)를 갖도록 블록을 단순화했다. 이 구조가 최적화에 유리했다.
\(\text{ResNet}(x) = \text{Prediction}(\text{ResNetBlock}(\dots(\text{ResNetBlock}(\text{Linear}(x)))))\)
\(\text{ResNetBlock}(x) = x + \text{Dropout}(\text{Linear}(\text{Dropout}(\text{ReLU}(\text{Linear}(\text{BatchNorm}(x))))))\)
\(\text{Prediction}(x) = \text{Linear}(\text{ReLU}(\text{BatchNorm}(x)))\)
3.3 FT-Transformer
Feature Tokenizer + Transformer. 모든 feature(수치형·범주형)를 임베딩으로 바꾼 뒤, 그 임베딩들에 Transformer 레이어를 쌓는다.
\[\text{FT-Transformer}(x) = \text{Prediction}(\text{Block}(\dots(\text{Block}(\text{FeatureTokenizer}(x)))))\]
(a) Feature Tokenizer
입력 feature $x$를 임베딩 $T \in \mathbb{R}^{k \times d}$로 변환한다. feature $x_j$에 대한 임베딩은:
\[T_j = b_j + f_j(x_j) \in \mathbb{R}^d, \quad f_j : X_j \to \mathbb{R}^d\]
여기서 $b_j$는 $j$번째 feature bias이고,
수치형: $f_j^{(num)}$은 벡터 $W_j^{(num)} \in \mathbb{R}^d$와 element-wise 곱
\(T_j^{(num)} = b_j^{(num)} + x_j^{(num)} \cdot W_j^{(num)} \in \mathbb{R}^d\)
범주형: $f_j^{(cat)}$은 lookup table $W_j^{(cat)} \in \mathbb{R}^{S_j \times d}$
\(T_j^{(cat)} = b_j^{(cat)} + e_j^{T} W_j^{(cat)} \in \mathbb{R}^d\)
($e_j$는 해당 범주형 feature의 one-hot 벡터)
모든 토큰을 쌓으면:
\[T = \text{stack}\left[T_1^{(num)}, \dots, T_{k^{(num)}}^{(num)}, T_1^{(cat)}, \dots, T_{k^{(cat)}}^{(cat)}\right] \in \mathbb{R}^{k \times d}\]
여기서 feature bias($b_j$)가 중요한 설계 요소다. 이걸 빼면 성능이 눈에 띄게 떨어진다.
(b) Transformer
여기에 [CLS] 토큰(출력 토큰)을 붙이고 $L$개의 Transformer 레이어 $F_1, \dots, F_L$을 적용한다:
\[T_0 = \text{stack}[\,[\text{CLS}],\ T\,], \qquad T_i = F_i(T_{i-1})\]
PreNorm 변형을 사용한다(최적화가 쉬움). 즉 정규화를 각 residual branch의 시작에 둔다.
PreNorm 세팅에서 좋은 성능을 위해 첫 번째 Transformer 레이어의 첫 정규화를 제거해야 했다.
Norm: LayerNorm
\(\text{Block}(x) = \text{ResidualPreNorm}(\text{FFN},\ \text{ResidualPreNorm}(\text{MHSA},\ x))\)
\(\text{ResidualPreNorm}(\text{Module}, x) = x + \text{Dropout}(\text{Module}(\text{Norm}(x)))\)
\(\text{FFN}(x) = \text{Linear}(\text{Dropout}(\text{Activation}(\text{Linear}(x))))\)
(c) Prediction
마지막 레이어의 [CLS] 토큰 표현으로 예측한다:
\[\hat{y} = \text{Linear}(\text{ReLU}(\text{LayerNorm}(T_L^{[\text{CLS}]})))\]
Limitations
ResNet 같은 단순 모델보다 학습에 더 많은 자원과 시간이 든다.
vanilla MHSA의 feature 수에 대한 Quadratic 복잡도 때문에 feature가 너무 많은 데이터에는 확장이 어렵다. (완화책: 어텐션 근사, 또는 FT-Transformer를 단순 구조로 distillation)
3.4 비교 대상 모델들
tabular 데이터 전용으로 설계된 기존 모델들도 함께 비교했다.
모델
계열 / 특징
SNN
SELU 활성화로 더 깊은 학습을 가능케 한 MLP 계열
NODE
oblivious decision tree의 미분 가능 앙상블
TabNet
feature 재가중과 FFN을 번갈아 쓰는 recurrent 구조
GrowNet
gradient boosted 약한 MLP들 (분류·회귀만 지원)
DCN V2
MLP 모듈 + feature crossing 모듈
AutoInt
feature를 임베딩 후 어텐션 기반 변환 적용
XGBoost
대표적 GBDT 구현
CatBoost
oblivious decision tree를 weak learner로 쓰는 GBDT
4. Experiments
이 논문은 아키텍처가 부여하는 inductive bias 자체를 평가하는 데 초점을 둔다. 따라서 pretraining, 추가 loss, data augmentation, distillation, learning rate warmup/decay 같은 기법은 사용되지 않았다.
데이터셋 (11개)
다양한 공개 데이터셋 11개를 사용하며, 각 데이터셋은 정확히 하나의 train-val-test split을 공유한다. 랭킹 문제(Microsoft, Yahoo)는 pointwise 방식으로 회귀 취급.
약자
데이터셋
#객체
#수치
#범주
metric
#클래스
CA
California Housing
20,640
8
0
RMSE
–
AD
Adult
48,842
6
8
Acc.
2
HE
Helena
65,196
27
0
Acc.
100
JA
Jannis
83,733
54
0
Acc.
4
HI
Higgs Small
98,050
28
0
Acc.
2
AL
ALOI
108,000
128
0
Acc.
1000
EP
Epsilon
500,000
2000
0
Acc.
2
YE
Year
515,345
90
0
RMSE
–
CO
Covertype
581,012
54
0
Acc.
7
YA
Yahoo
709,877
699
0
RMSE
–
MI
Microsoft
1,200,192
136
0
RMSE
–
Preprocessing
기본적으로 scikit-learn의 quantile transformation 사용.
Helena, ALOI에는 standardization 적용(ALOI는 이미지 데이터라 CV 관례를 따름).
Epsilon은 전처리가 오히려 성능을 저하시켜 raw feature 사용.
모든 알고리즘에서 회귀 문제의 타깃은 standardization적용.
Tuning
대부분 모델은 Optuna로 베이지안 최적화(TPE) 수행. 나머지는 각각의 원래 논문이 권장한 설정 조합을 순회.
하이퍼파라미터는 validation set 성능으로 선택(test는 절대 튜닝에 안 씀).
Evaluation
튜닝된 각 구성에 대해 서로 다른 랜덤 시드 15개로 실험 후 test 성능 보고.
Ensembles
각 모델·데이터셋마다 15개 단일 모델을 크기가 같은 3개 그룹으로 나눠, 그룹 내 예측을 평균 → 앙상블 3개 확보.
학습 세부
분류: cross-entropy, 회귀: MSE.
Optimizer: TabNet·GrowNet은 Adam, 나머지는 AdamW. learning rate schedule 없음.
Early stopping: patience = 16 (16+1 epoch 동안 val 개선 없으면 종료).
범주형: XGBoost는 one-hot, CatBoost는 내장 지원, NN은 동일 차원 임베딩.
5. 결과
Comparing DL models
ResNet은 효과적인 베이스라인. 평균 순위 3.3으로 DL 모델 중 2위.
FT-Transformer는 대부분 task에서 최고 성능(평균 순위 1.8)
튜닝이 MLP·ResNet 같은 단순 모델을 경쟁력 있게 만든다. 따라서 가능하면 베이스라인도 튜닝하기를 권한다.
NODE는 몇몇 태스크에서 높은 성능을 보이지만, 복잡한 구조임에도 ResNet보다 6개 데이터셋(HE, JA, HI, AL, EP, CO)에서 낮은 성능을 보여줌.
Comparing DL models and GBDT
Default 하이퍼파라미터 관점
FT-Transformer 앙상블이 대부분 GBDT 앙상블을 능가
default FT-Transformer 앙상블이 tuned FT-Transformer 앙상블과 거의 비슷한 성능을 보임.
Tuned 하이퍼파라미터 관점
제대로 튜닝하면 GBDT가 일부 데이터셋(CA, AD, YA)에서 우위를 점하고, 그 격차가 유의미하다.
즉 딥러닝이 GBDT를 보편적으로 이기는 것은 아니다. 또한 벤치마크 자체가 약간 “DL-friendly”하게 편향됐을 수 있음을 저자들도 인정함.
GBDT는 클래스가 많은 다중 분류에는 부적합하다(Helena에서 성능 저조, ALOI는 학습이 너무 느려 튜닝 불가).
6. Analysis
When FT-Transformer is better than ResNet?
두 모델의 성능 차이가 극적으로 변하도록 합성 태스크를 설계했다.
\[x \sim N(0, I_k), \qquad y = \alpha \cdot f_{GBDT}(x) + (1-\alpha)\cdot f_{DL}(x)\]
$f_{GBDT}$: 랜덤하게 구성한 30개 결정 트리의 평균 예측 (GBDT에 유리하게 설계)
$f_{DL}$: 랜덤 초기화된 3개 hidden layer MLP (ResNet에 유리하게 설계)
$\alpha$가 0(=DL-friendly)에서 1(=GBDT-friendly)로 변할 때:
$\alpha$가 작을 때(DL-friendly): ResNet과 FT-Transformer 모두 비슷하게 준수한 성능을 보이며 CatBoost를 능가함.
$\alpha$가 커질 때(GBDT-friendly): ResNet의 상대 성능이 급격히 하락.
반면 FT-Transformer는 전 구간에서 경쟁력을 유지.
이 실험은 “FT-Transformer가 ResNet보다 잘 근사하는 함수 유형”이 존재함을 보여주며, 그 함수가 결정 트리 기반이라는 점이 관찰(= GBDT가 우세한 데이터셋에서 FT-Transformer의 개선이 가장 확실함)과 일치한다.
Obtaining feature importances from attention maps
FT-Transformer의 어텐션 맵을 feature importance의 원천으로 활용할 수 있다. $i$번째 샘플에 대해 [CLS] 토큰의 평균 어텐션 맵 $p_i$를 구하고, 이를 전체 샘플에 대해 평균낸다:
\[p = \frac{1}{n_{samples}} \sum_i p_i, \qquad p_i = \frac{1}{n_{heads} \times L} \sum_{h,l} p_{ihl}\]
($p_{ihl}$ = $l$번째 레이어, $h$번째 head의 [CLS] 어텐션 맵)
장점은 효율성 — 샘플당 forward 한 번이면 된다. 이를 Integrated Gradients(IG), Permutation Test(PT)와 비교(PT 랭킹과의 rank correlation 측정):
단순 어텐션 맵 평균이 IG와 비슷한 수준의 feature importance를 준다. IG는 수십~수백 배 느릴 수 있고 PT는 (feature 수 + 1)번의 forward가 필요한 반면, 이 방법은 forward 한 번이면 되므로 비용 대비 효과가 좋은 선택이다. (단, IG와 성능이 비슷하다는 게 IG와 importance가 동일하다는 뜻은 아니다.)
그 외
FT-Transformer는 ResNet보다 느리다. feature가 많은 Yahoo(699개)에서는 약 13.8배 오버헤드가 발생 — 어텐션의 이차 복잡도 탓.
FT-Transformer는 랜덤 샘플링된 몇 개 구성만으로도 좋은 지표에 도달한다. 즉 FT-Transformer의 강한 성능이 “더 오래 튜닝해서”가 아니라는 것도 확인된다. 반대로 다른 알고리즘은 iteration을 크게 늘려도 의미 있는 개선이 없었다.
Conclusion
이 논문은 Tabular 데이터에서 딥러닝 모델의 성능을 확인하고, 베이스라인 수준을 향상시켰다.
ResNet 계열의 단순한 구조가 효과적인 베이스라인이 될 수 있음을 보였다.
FT-Transformer를 제안했고, 대부분의 태스크에서 다른 딥러닝 모델을 능가했다.
이 새로운 베이스라인들을 GBDT와 비교한 결과, 일부 태스크에서는 여전히 GBDT가 우위를 지킨다는 점도 확인했다.
-
[ML] XGBoost
참고한/사용된 자료
Krish Naik의 ‘Complete Data Science,Machine Learning,DL,NLP Bootcamp’ 강의 내용을 참고하여 작성한 글입니다.
Udemy
강의자료(Github)
XGBoost
XGBoost(Extreme Gradient Boosting)는 Gradient Boosting을 기반으로, 여기에 정규화(Regularization)와 효율적인 분기 탐색 방식을 더해 성능과 속도를 개선한 알고리즘이다. Gradient Boosting과 마찬가지로 여러 개의 Weak Learner(Tree)를 순차적으로 학습시켜 이전 모델의 잔차를 보완해나가는 큰 틀은 동일하지만, 트리를 어떤 기준으로 분기할지, 그리고 각 리프(Leaf)의 예측값을 어떻게 정할지를 정의하는 방식이 조금 다르다.
학습 과정 (Regressor 기준)
먼저, 모든 샘플에 대해 동일한 초기 예측값에서 시작한다. Gradient Boosting과 마찬가지로 첫 Base Model은 보통 예측 레이블의 평균값을 출력하며, 그 후 실제값과 초기 예측값(평균)의 차이인 잔차 $R_1$를 계산한다.
다음으로 의사결정 트리를 생성하는데, 원래의 타겟값이 아닌 이 잔차를 예측하도록 학습된다. 모든 데이터 $(X, R_1)$를 가진 하나의 Root Node에서 시작해, 가능한 모든 (Feature, threshold) 조합에서 데이터를 둘로 나눴을 때의 Gain을 계산한다.
Gain을 계산하기 위해서 Similarity Score를 계산해야 한다. Similarity Score는 한 노드 안에 모인 잔차($R_1$)들이 얼마나 “일관된 방향을 가리키는지”를 나타내는 지표다. 잔차들이 서로 비슷한 방향(부호와 크기)을 가질수록 값이 커진다.
\[\text{Similarity Score} = \frac{\left(\displaystyle\sum_{i=1}^{n} r_i\right)^2}{n + \lambda}\]
$r_i$ : 해당 노드에 속한 $i$번째 샘플의 잔차
$n$ : 해당 노드에 속한 샘플 수
$\lambda$ : 정규화(Regularization) 파라미터
Gain은 하나의 노드를 둘(Left/Right)로 나눴을 때, 그 분기가 얼마나 좋은 선택인지를 나타내는 지표다. 분기 전(Root)보다 분기 후(Left + Right)의 Similarity 합이 클수록 좋은 분기다.
\[\text{Gain} = \text{Similarity}_{\text{Left}} + \text{Similarity}_{\text{Right}} - \text{Similarity}_{\text{Root}}\]
이렇게 각 (Feature, threshold) 조합에 대해 구한 트리에서 Gain이 가장 큰 조합으로 트리를 분기한다. 이 과정을 트리가 정해진 깊이(max_depth)에 도달하거나 더 이상 나눌 데이터가 없을 때까지 반복한다. 트리가 완성되면, 이렇게 만들어진 분기들 중 불필요한 것을 가지치기한다.
※ 만약 가장 좋은 Gain조차 정해둔 임계값 $\gamma$보다 작다면(즉 $\text{Gain} - \gamma < 0$), 그 분기는 가지치기한다. $\gamma$는 트리가 너무 잘게 쪼개지는 것을 막는 Hyperparameter로, 트리를 최대 깊이까지 모두 성장시킨 뒤 가지치기(post-pruning)를 적용한다.
트리가 생성되었으면 각 리프(Leaf)의 출력값을 계산한다. 데이터가 들어오면 기준에 따라 leaf node에 도달하게 되고, 도달한 노드에 속한 잔차들을 바탕으로 그 리프의 최종 출력값을 계산한다. 회귀의 경우 아래 식처럼 정규화 항이 포함된 평균값을 사용한다.
\[\text{Output Value} = \frac{\displaystyle\sum_{i=1}^{n} r_i}{n + \lambda}\]
이렇게 구한 트리의 예측값에 Learning Rate $\alpha$를 곱하여 반영한다.
\[\hat{y} \leftarrow \hat{y} + \alpha \cdot (\text{Output Value})\]
이렇게 갱신된 예측값을 기준으로 잔차를 다시 계산하고, 같은 과정을 반복해 다음 트리를 학습시킨다. 이 과정을 정해진 트리 개수만큼 반복하며 모델 전체를 학습시킨다.
※ Similarity Score, Output value 수식 모두 분모에 $\lambda$가 들어있다. $\lambda$가 커질수록 두 값 모두 작아지는데, 이는 노드에 속한 샘플 수($n$)가 적거나 잔차 합이 우연히 크게 나온 경우(이상치의 영향 등)에 모델이 과도하게 확신을 갖지 않도록 억제하는 효과를 낸다.
XGBoost Classifier
log-odds
Classifier의 차이를 이해하려면 먼저 log-odds 개념을 짚고 넘어가야 한다. log-odds는 확률 $p$를 아래처럼 변환한 값이다.
\[\text{log-odds} = \log\left(\frac{p}{1-p}\right)\]
확률 $p$는 항상 $[0, 1]$ 사이 값이어야 하지만, log-odds는 $-\infty$부터 $+\infty$까지 자유로운 실수값을 가진다. Boosting은 여러 트리의 출력값을 계속 더해나가는 방식인데, 만약 이 덧셈을 확률 공간에서 그대로 하면 값이 금방 [0, 1]에서 벗어나 확률로서의 의미가 깨진다. 그래서 트리의 출력을 확률이 아닌 log-odds 공간에서 자유롭게 더하고, 확률이 필요한 순간에만 sigmoid 함수로 변환한다.
\[p = \frac{1}{1 + e^{-\text{log-odds}}}\]
예를 들어 $p=0.5$일 때 log-odds는 정확히 0이고, $p$가 1에 가까워질수록 log-odds는 $+\infty$로, 0에 가까워질수록 $-\infty$로 발산한다.
Classifier의 차이점
Classifier의 전체 흐름(잔차 계산 → 분기 → Output Value 계산 → 예측값 업데이트)은 Regressor와 동일하지만, 다루는 값의 형태와 일부 수식이 달라진다.
초기 예측값: 회귀에서는 보통 평균값에서 출발하지만, 분류에서는 확률 0.5, 즉 log-odds값 0에서 출발한다.
잔차: 실제 클래스($y_i \in {0, 1}$)와 예측 확률 $p_i$의 차이로 정의된다.
\[r_i = y_i - p_i\]
Similarity Score / Output Value의 분모: 회귀에서는 단순히 샘플 개수 $n$을 사용했지만, 분류에서는 각 샘플의 $p_i(1-p_i)$ 값을 모두 더한 값으로 바뀐다. 이는 로지스틱 손실 함수를 사용하기 때문에 나타나는 차이로, 예측 확률이 0.5에 가까워 불확실한 샘플일수록 이 값이 커진다.
\[\text{Similarity Score} = \frac{\left(\displaystyle\sum_{i=1}^{n} r_i\right)^2}{\displaystyle\sum_{i=1}^{n} p_i(1-p_i) + \lambda}\]
\[\text{Output Value} = \frac{\displaystyle\sum_{i=1}^{n} r_i}{\displaystyle\sum_{i=1}^{n} p_i(1-p_i) + \lambda}\]
예측값 업데이트와 확률 변환: Output Value는 확률이 아니라 log-odds 공간에 더해진다. 즉 log-odds를 업데이트한 뒤, 이를 다시 시그모이드 함수로 변환해야 확률값을 얻을 수 있다.
\[\text{log-odds} \leftarrow \text{log-odds} + \alpha \cdot (\text{Output Value})\]
\[p = \frac{1}{1 + e^{-\text{log-odds}}}\]
정리하면, Regressor와 Classifier의 차이는 결국 “분모에 어떤 값을 쓰는가”와 “결과값을 어느 공간(실수값 vs log-odds)에서 다루는가” 두 가지로 요약할 수 있다. 트리를 분기하고 Gain을 비교해 가장 좋은 구조를 찾는 핵심 로직 자체는 두 경우 모두 동일하다.
-
[ML] Gradient Boosting
참고한/사용된 자료
Krish Naik의 ‘Complete Data Science,Machine Learning,DL,NLP Bootcamp’ 강의 내용을 참고하여 작성한 글입니다.
Udemy
강의자료(Github)
Gradient Boosting 소개
Gradient Boosting은 Ensemble 기법 중 Boosting 계열에 속하는 알고리즘이다. AdaBoost와 마찬가지로 여러 개의 Weak Learner를 순차적으로 학습시켜 하나의 Strong Learner를 만들어내지만, 순차적으로 보완하는 대상이 다르다. AdaBoost가 샘플의 가중치를 조정해가며 이전에 틀렸던 샘플에 더 집중하는 방식이라면, Gradient Boosting은 이전 모델이 설명하지 못한 잔차(residual)를 다음 Weak Learner가 직접 학습하도록 하는 방식으로 작동한다.
기본 아이디어
먼저 아주 단순한 초기 예측값(예: 전체 타겟값의 평균)으로 모델을 시작한다. 첫 Weak Learner는 모든 입력 $X$에 대해 타겟값의 평균을 항상 내놓는다.
이 초기 예측값과 실제값의 차이, 즉 잔차 $R_1$을 계산한다. 다음 Weak Learner는 원래의 타겟값이 아닌 이 잔차를 예측하도록 학습된다.
새로 학습된 Weak Learner의 예측값(잔차)을 기존 예측값 $\hat{y}$에 더해 전체 예측을 업데이트한다. 이때 예측한 값을 그대로 더하는 것이 아니라, Learning Rate $\alpha$를 곱하여 더한다.
이 과정을 정해진 횟수만큼 반복하면서, 매 라운드마다 잔차를 조금씩 줄여나가는 방식이다.
즉 각 Weak Learner는 “정답이 무엇인가”를 직접 맞히는 것이 아니라, “지금까지의 모델이 아직 설명하지 못한 오차가 무엇인가”를 맞히는 역할을 한다. 라운드가 거듭될수록 잔차는 점점 작아지고, 전체 모델의 최종 예측값은 실제값에 점점 가까워진다.
\[F(x) = \sum_{t=1}^{T} \alpha_t \, h_t(x)\]
$h_t(x)$ : $t$번째 Weak Learner의 예측값
$\alpha_t$ : $t$번째 Weak Learner의 가중치(Learning Rate)
$T$ : 전체 반복(Weak Learner) 횟수
왜 ‘Gradient’라는 이름이 붙었는가
일반적인 경사하강법(Gradient Descent)은 파라미터 $\theta$를 손실 함수의 그래디언트 반대 방향으로 조금씩 이동시키며 손실을 줄여나가는 방법이다.
\[\theta \leftarrow \theta - \eta \cdot \frac{\partial L}{\partial \theta}\]
Gradient Boosting은 이와 같은 아이디어를 가중치가 아니라 예측값 $\hat{y}$ 자체에 적용한 것이다. 회귀 문제에서 자주 쓰는 손실 함수인 제곱오차(Squared Error)를 예로 들어보자.
\[L(y, \hat{y}) = \frac{1}{2}(y - \hat{y})^2\]
이 손실 함수를 예측값 $\hat{y}$에 대해 미분하면 다음과 같다.
\[\frac{\partial L}{\partial \hat{y}} = -(y - \hat{y})\]
여기에 음수를 붙인 negative gradient는,
\[-\frac{\partial L}{\partial \hat{y}} = y - \hat{y} = \text{잔차}\]
즉 잔차 자체가 손실 함수의 negative gradient와 정확히 같다. 그래서 앞서 살펴본 “다음 Weak Learner가 잔차를 학습해서 예측값에 더한다”는 과정은, 사실 “예측값 $\hat{y}$를 손실이 줄어드는 방향(negative gradient 방향)으로 한 걸음 이동시킨다”는 것과 동일한 의미다.
\[\hat{y} \leftarrow \hat{y} + \alpha \cdot \left(-\frac{\partial L}{\partial \hat{y}}\right)\]
여기서 앞서 등장했던 Learning Rate $\alpha$는, 일반적인 경사하강법의 학습률과 정확히 같은 역할을 한다. 즉 Gradient Boosting이라는 이름은 “예측값을 파라미터처럼 취급하고, 손실 함수의 그래디언트를 따라 조금씩 개선한다”는 학습 방식 자체를 그대로 표현한 이름이다.
이렇게 손실 함수의 관점에서 바라보면, 손실 함수를 제곱오차가 아닌 다른 함수(예: 분류 문제의 로그 손실)로 바꾸는 것만으로 같은 프레임워크를 회귀, 분류 등 다양한 문제에 적용할 수 있다.
실제로 AdaBoost는 지수 손실 함수를 최소화하는 특수한 경우로 볼 수 있고, Gradient Boosting은 이를 임의의 손실 함수로 일반화한 프레임워크라고 볼 수 있다. (AdaBoost는 Gradient Boosting의 한 특수 사례로 해석할 수 있다.)
-
[ML] AdaBoost
참고한/사용된 자료
Krish Naik의 ‘Complete Data Science,Machine Learning,DL,NLP Bootcamp’ 강의 내용을 참고하여 작성한 글입니다.
Udemy
강의자료(Github)
1. AdaBoost 소개
AdaBoost(Adaptive Boosting)는 Ensemble 기법 중 Boosting 계열에 속하는 알고리즘이다. 성능이 약한 여러 개의 Weak Learner를 순차적으로 학습시켜, 이들을 결합해 하나의 Strong Learner를 만들어내는 것이 핵심 아이디어다.
Random Forest와 같은 Bagging 계열 알고리즘이 여러 모델을 독립적으로 학습시킨 뒤 다수결(또는 평균)로 결과를 결정하는 것과 달리, AdaBoost는 Weak Learner를 순차적으로 학습시키면서 이전 모델이 잘못 예측한 데이터에 가중치를 부여해 다음 모델이 이를 보완하도록 만든다. 즉, 각 모델이 독립적이지 않고 이전 모델의 결과에 종속적으로 학습된다는 점이 가장 큰 차이다.
Bias-Variance 관점에서 보는 AdaBoost
“High Bias, Low Variance 상태에서 Low Bias, High Variance 상태로 이동한다”는 분산이 커지는게 언뜻 성능 저하처럼 보일 수 있지만, 실제로는 그렇지 않다.
모델의 일반화 오차는 대략 다음과 같이 분해할 수 있다.
\[전체 오차 ≈ Bias² + Variance + 줄일 수 없는 노이즈\]
우리가 궁극적으로 줄여야 하는 것은 분산 그 자체가 아니라 이 오차의 합이라는 점이 핵심이다.
Weak Learner 1개: 단순한 모델은 데이터를 충분히 학습하지 못해 Bias가 크다. 대신 모델 구조가 단순해서 학습 데이터가 조금 바뀌어도 예측이 크게 흔들리지 않으므로 Variance는 작다.
AdaBoost의 결합 과정: Weak Learner를 순차적으로 이어 붙여 이전 모델이 틀린 부분에 가중치를 부여해 학습하기 때문에, 모델 전체의 표현력(capacity)이 커지고 Bias가 줄어든다. 다만 표현력이 커진 만큼 학습 데이터의 패턴에 더 민감해지므로 Variance는 다소 증가한다.
표현력(capacity)이란?
모델이 표현할 수 있는 함수/결정 경계(decision boundary)가 얼마나 복잡한가를 뜻한다. Weak Learner 1개는 단순한 경계만 그릴 수 있다면, 이런 Weak Learner를 여러 개 결합하면 각 경계들이 겹쳐지면서 훨씬 복잡한 결정 경계를 만들 수 있게 된다. 즉 Weak Learner를 더할수록 앙상블 전체의 표현력이 커지는 것이다.
이때 Bias가 줄어드는 폭이 Variance가 늘어나는 폭보다 훨씬 크기 때문에, 전체 오차는 오히려 감소하고 앙상블의 예측 성능은 개별 Weak Learner보다 좋아진다. 따라서 “Low Bias, High Variance”라는 표현은 Weak Learner 하나와 비교했을 때 상대적으로 그렇다는 의미이지, Variance가 안좋은 수준까지 높아진다는 뜻은 아니다.
물론 Weak Learner 개수를 무한정 늘린다고 성능이 계속 좋아지는 것은 아니다. 어느 시점부터는 Bias는 거의 줄어들지 않고 Variance만 커지는 구간이 나타나는데, 이것이 바로 과적합(Overfitting)으로 이어진다. 그래서 실전에서는 반복 횟수를 적절히 제한하거나, Learning Rate를 통해 각 Weak Learner의 기여도를 낮추는 방식으로 Variance 증가를 통제한다.
Random Forest와의 비교
구분
Random Forest (Bagging)
AdaBoost (Boosting)
학습 방식
독립적 · 병렬 학습
순차적 학습
결과 결합 방식
다수결 / 평균
가중 합
개별 모델 특성
Low Bias, High Variance (깊은 트리)
High Bias, Low Variance (Weak Learner)
앙상블의 목적
Variance 감소
Bias 감소
두 알고리즘 모두 “적당한 Bias + 적당한 Variance”를 만들기 위한 알고리즘이며, Random Forest는 이미 Variance가 큰 모델들을 평균 내어 Variance를 낮추는 전략이고, AdaBoost는 Bias가 큰 모델들을 순차적으로 보완해 Bias를 낮추는 전략이다.
2. AdaBoost 설계
Weak Learner: Decision Stump
일반적으로 Boosting 계열 앙상블 모델에서 Weak Learner로는 Decision Tree가 많이 사용되며, AdaBoost에서는 그중 가장 단순한 형태인 깊이가 1인 Decision Tree를 사용한다. 이를 Decision Stump라고 부른다.
깊이가 1이라는 것은 Root Node에서 딱 한 번의 분기만 일어난 형태이다. 즉 전체 Feature 중 단 하나의 Feature와 하나의 기준값(threshold)만으로 데이터를 두 그룹(Yes/No)으로 나누는, 가장 얕은 형태의 분류기다. 그만큼 단독으로는 예측 성능이 낮지만(High Bias), 계산이 빠르고 특정 데이터에 과하게 민감하게 반응하지 않는다는(Low Variance) 장점이 있다. 앞서 살펴본 것처럼 AdaBoost는 이런 Decision Stump를 여러 개 순차적으로 쌓아 올려 Bias를 낮춰가는 구조다.
최종 예측 수식
최종 분류 결과 F(x)는 각 Weak Learner의 예측값에 가중치를 곱해 더한 형태로 표현된다.
\[F(x) = α₁ · m₁(x) + α₂ · m₂(x) + ... + αₙ · mₙ(x)\]
$mₜ(x)$: t번째 Weak Learner(Decision Stump)가 입력 x에 대해 내놓은 예측값. 이진 분류 문제에서는 보통 +1 또는 -1의 값을 갖는다.
$αₜ$: t번째 Weak Learner의 가중치(Performance of Stump). 해당 Stump가 학습 데이터를 얼마나 잘 맞췄는지에 따라 결정되며, 오차율이 낮을수록(=잘 맞출수록) 값이 커지고, 오차율이 높을수록 최종 예측에 미치는 영향력은 작아진다.
즉 모든 Stump가 동등한 영향력을 행사하는 것이 아닌, 더 잘 맞춘 Stump가 더 큰 영향을 가진다는 것이 AdaBoost 결합 방식의 핵심이다.
3. AdaBoost 작동 과정
Decision Stump 생성
Decision Stump를 만들기 위해 기준이될 Feature를 무작위로 고르는 것이 아니라, 모든 Feature와 가능한 모든 분기 기준(threshold)을 탐색하여 가중 오차(weighted error, Total Error)가 가장 작은 조합을 선택한다. 완전 탐색에 가까운 방식이다.
먼저 데이터의 각각의 샘플은 가중치를 가지고 있다. 맨 처음에는 모든 샘플의 가중치가 동일하게 $w_i = 1/N$로 설정되며, 이후에도 전체 가중치의 합이 항상 1이 되도록 정규화가 유지된다.
이후 아래의 과정을 통해 매 반복마다 Decision Stump를 생성한다.
모든 Feature를 하나씩 후보로 검토한다.
각 Feature에 대해 데이터를 정렬한 뒤, 가능한 분기 기준(threshold) 후보를 만든다. 보통 정렬된 값들 사이의 중간점(midpoint)을 후보로 삼는다.
각 (Feature, threshold) 조합마다 그 기준으로 데이터를 Yes/No 두 그룹으로 나눴을 때의 Weighted Error를 계산한다.
모든 (Feature, threshold) 조합 중 가중 오차가 가장 낮은 조합을 최종 Stump로 선택한다.
Total Error(Weighted Error)는 일반적으로 다음과 같이 정의된다.
\[\text{Total Error} = \frac{\displaystyle\sum_{i \,:\, \hat{y}_i \neq y_i} w_i}{\displaystyle\sum_{i=1}^{N} w_i}\]
AdaBoost에서는 매 반복마다 샘플 가중치의 총합이 1이 되도록 정규화하기 때문에, 분모가 항상 1이 되어 다음과 같이 단순화된다.
\[\text{Total Error} = \sum_{i \,:\, \hat{y}_i \neq y_i} w_i\]
$w_i$ : $i$번째 샘플의 가중치
$\hat{y}_i \neq y_i$ : 예측값과 실제값이 다른, 즉 오분류된 샘플
$N$ : 전체 샘플 개수
강의자료에서는 샘플 1개가 오분류 되어 $1/7$이 Total Error가 되었다.
선택 로직 자체는 매 반복마다 동일하지만, 맨처음에는 모든 샘플의 가중치가 동일($w_i = 1/N$)하다는 점에서 첫 번째 Stump는 전체 데이터셋 기준으로 가장 잘 나누는 Feature와 threshold를 찾는 과정이다.
두 번째 반복부터는 이전 라운드에서 틀린 샘플의 가중치가 커진 상태이기 때문에, 같은 탐색 과정을 거치더라도 틀렸던 샘플들을 더 잘 맞추는 방향으로 다른 Feature/threshold가 선택될 가능성이 높아진다.
Performance of Decision Stump
Total Error는 위에서처럼 (Feature, threshold) 조합의 Stump를 선택하는 기준임과 동시에 Performance of Stump($\alpha$)를 계산하는데 필요한 값이다.
Performance of Stump($\alpha$)는 다음과 같이 구한다:
\[\alpha = \frac{1}{2} \ln\left(\frac{1 - \text{Total Error}}{\text{Total Error}}\right)\]
Updating Weights
이제 각 샘플의 분류 결과에 따라 정분류된 샘플의 가중치는 줄이고, 오분류된 샘플의 가중치는 증가시킨다.
샘플 $i$의 새 가중치는 다음과 같이 계산한다. (분류 기준 설명)
\[w_i \leftarrow w_i \cdot e^{-\alpha \, y_i \, h(x_i)}\]
여기서 $y_i$는 실제 레이블, $h(x_i)$는 이번 Stump의 예측값으로 둘 다 $+1$ 또는 $-1$ 값을 갖는다. 이 식은 정분류/오분류 여부에 따라 아래처럼 두 가지 경우로 나뉜다.
\[w_i \leftarrow
\begin{cases}
w_i \cdot e^{-\alpha} & (\text{정분류된 경우}) \\
w_i \cdot e^{\alpha} & (\text{오분류된 경우})
\end{cases}\]
$\alpha > 0$인 일반적인 상황을 기준으로 보면, 정분류된 샘플은 $e^{-\alpha} < 1$이 곱해져 가중치가 줄어들고, 오분류된 샘플은 $e^{\alpha} > 1$이 곱해져 가중치가 커진다. 이렇게 갱신된 가중치는 전체 합으로 나누어 다시 총합이 1이 되도록 정규화한다.
\[w_i \leftarrow \frac{w_i}{\displaystyle\sum_{j=1}^{N} w_j}\]
Boosting by Reweighting
다음 Weak Learner에게 데이터를 전달할 때, 데이터셋 자체는 그대로 두고 각 샘플의 가중치를 계속 누적해서 업데이트하는 방식이다.
다음 Weak Learner는 이 가중치를 직접 반영한 가중 손실(weighted Gini, weighted error 등)을 계산해 위 과정을 반복한다. 가중치는 매 반복마다 리셋되지 않고, 이전 값 위에 이어서 갱신되는 방식이다.
Boosting by Resampling
강의자료에서 설명하는 방식으로, 가중치를 확률분포로 변환한 뒤(누적합으로 Bins를 만들고) 그 분포를 따라 N개의 샘플을 복원추출(bootstrap)한다.
이렇게 하면 가중치가 큰(=Error가 컸던) 샘플일수록 뽑힐 확률이 높아지고, 실제로 다음 데이터셋에 여러 번 중복돼서 포함된다. 그 결과 다음 Weak Learner는 이전에 틀렸던 샘플들을 자연스럽게 더 많이 마주치며 학습하게 된다.
새로 뽑힌 데이터셋 안에서는 중요한 샘플일수록 이미 여러 번 중복되어 들어가 있으므로, 가중치로 별도의 중요도를 표시할 필요가 없다. 그래서 다음 learner는 이 새 데이터셋을 대상으로 모든 샘플이 다시 균등한 가중치($w_i = 1/N$)에서 시작한다.
두 방식은 같은 목표를 다르게 구현한 것이다. “가중치가 큰 샘플에게 다음 라운드에서 더 큰 영향력을 준다”는 목표는 동일하지만, Reweighting은 가중치를 숫자로 직접 전달하는 방식이고 Resampling은 그 가중치만큼 샘플을 물리적으로 복제해서 전달하는 방식이다. 표본 크기가 충분히 크다면 기댓값 관점에서 두 방식은 동등한 효과를 낸다. 다만 Resampling은 복원추출 과정에서 추가적인 무작위성(sampling noise)이 개입되어, 운이 나쁘면 중요한 샘플이 이번 라운드에 하나도 뽑히지 않을 수도 있다. 이 때문에 scikit-learn 등 실제 구현체 다수는 Resampling 대신 Reweighting(가중 손실 기반 분기)을 사용한다.
Final Prediction
이후의 학습 과정은 지금까지의 과정(Decision Stump 생성 → Performance 계산 → Weight Update → 다음 데이터셋 구성)을 정해진 반복 횟수 $T$만큼 반복하는 것이다. 매 반복마다 새로 구성된 데이터셋을 받은 Weak Learner는 다시 균등한 가중치로 시작해 같은 과정을 되풀이한다.
이렇게 $T$개의 Decision Stump $m_1, m_2, \dots, m_T$와 각각의 Performance $\alpha_1, \alpha_2, \dots, \alpha_T$가 모두 구해지면, 앞서 다룬 최종 예측 수식에 따라 이들을 가중합한 뒤 부호(sign)를 취해 최종 클래스를 결정한다.
※ 이 방식은 이진 분류 기준이며, 다중 클래스 분류의 경우 다른 방식의 확장이 필요하다
\[F(x) = \text{sign}\left(\sum_{t=1}^{T} \alpha_t \, m_t(x)\right)\]
-
[ML] Decision Tree & Random Forest
참고한/사용된 자료
위키백과
https://process-mining.tistory.com/42
Data Science Diary
1. Decision Tree
Decision Tree는 Tree 구조를 활용해 데이터의 Entropy와 불순도(Impurity)가 최소화되는 방향으로 분기하며 분류 혹은 회귀를 수행하는 지도학습 알고리즘이다.
여러 레이블, 혹은 여러 분포의 값이 섞여있는 데이터에서 시작하여 트리의 leaf node에 도달하면 최대한 어떤 범주의 데이터들로만 구성되도록 데이터를 나누는 것이다.
불순도(Impurity)
불순도란 어떤 데이터 집합에 서로 다른 범주(Class)의 데이터가 얼마나 섞여 있는지를 나타내는 수치이다. 수치가 높을수록 여러 범주의 데이터가 섞여 있는 상태이고, 반대로 수치가 0에 가까울수록 하나의 범주로만 깔끔하게 구성된 순수한 상태(Pure)를 의미한다.
의사결정나무는 자식 노드로 분기할 때 이 불순도를 최대한 줄여나가는 방향으로 기준을 설정한다. 불순도를 측정하는 대표적인 지표로 엔트로피(Entropy)와 지니 불순도(Gini Impurity)가 있다.
Entropy
어떤 노드 $S$에 대한 엔트로피는 다음과 같은 수식으로 계산한다.
\[Entropy(S) = - \sum_{i=1}^{c} p_i \log_2(p_i)\]
$c$ : 데이터의 범주(Class) 개수
$p_i$ : 해당 노드에서 $i$번째 범주가 차지하는 비율 (확률)
엔트로피는 0~1 사이의 값을 가지며 데이터가 50:50 비율일때 최댓값을 가진다.
지니 불순도(Gini Impurity)
지니 불순도는 데이터 집합에서 하나의 데이터를 뽑아 무작위로 레이블을 예측할 때, 잘못 분류될 확률을 의미한다.
임의로 뽑은 데이터가 실제 $i$번째 범주일 확률 = $p_i$
내가 그 데이터를 $i$번째 범주라고 무작위로 예측할 확률 = $p_i$
그렇다면 이 예측이 적중(맞을) 확률 = $p_i \times p_i = p_i^2$
모든 범주에 대해 예측이 전체적으로 맞을 확률 = $\sum_{i=1}^{c} p_i^2$
우리가 원하는 건 ‘순수한 정도’가 아니라 ‘불순한 정도(틀릴 확률)’이므로, 전체 확률인 1에서 맞을 확률을 뺀다.
\[Gini(S) = 1 - \sum_{i=1}^{c} p_i^2\]
엔트로피와 마찬가지로 데이터의 순도가 높을수록 0에 가까워지며, 50:50 비율일때 최댓값 0.5를 가진다.
Information Gain
정보 획득량(Information Gain)은 어떤 특징을 기준으로 데이터를 분할했을 때, 분할 전후로 불순도가 얼마나 감소했는가를 나타내는 지표이다. 불순도의 감소 수준을 나타내므로 Information Gain이 높을수록 좋은 분할이라는 것을 알 수 있다.
⇒ 결정 트리 알고리즘은 정보 획득을 최대화하는 방향으로 학습이 진행
엔트로피를 사용하여 설명하면, 정보 획득량은 부모 노드의 엔트로피에서 자식 노드들의 엔트로피 가중 평균을 뺀 값으로 계산한다.
\[IG(S, A) = Entropy(S) - \sum_{v \in Values(A)} \frac{|S_v|}{|S|} Entropy(S_v)\]
$S$ : 분할하기 전 부모 노드의 전체 데이터 집합
$A$ : 데이터를 분할하는 기준 (속성)
$S_v$ : 속성 $A$의 조건에 따라 분할된 자식 노드의 데이터 집합
$|S|$ : 부모 노드의 전체 데이터 개수
$|S_v|$ : 자식 노드의 데이터 개수
가지치기(Pruning)
트리의 분할이 너무 많아진다면 과적합이 발생할 수 있다. 트리의 최대 깊이, Leaf Node의 개수, 한 노드의 최소 데이터 수를 제한하여 적절한 크기의 트리가 만들어지도록 한다.
사전 가지치기 (Pre-Pruning): 트리가 생성될때부터 최대 깊이, 최소 데이터 수 제한 등으로 성장을 미리 멈춤. (데이터셋의 크기가 클때 사용하여 시간소요를 줄임)
사후 가지치기 (Post-Pruning): 트리를 완전히 성장시킨 후, 성능 향상에 크기 기여하지 않는 가지들을 제거하여 단순화. (시간 소요와 비용이 크기 때문에 적은 데이터셋을 다룰때 사용)
2. Ensemble, Bagging, Boosting
Ensemble
Ensemble(앙상블)은 머신러닝에서 여러 개의 개별 모델을 결합하여 하나의 더 강력한 모델을 만드는 기법이다. 단일 모델이 아닌 여러 모델의 예측을 결합하여 성능을 높이는 방식이며, 약한 모델(weak learner) 여러 개를 조합하면 더 강력한 모델(strong learner)이 될 수 있다는 것을 보여준다.
대표적인 앙상블 기법으로 배깅(Bagging)과 부스팅(Boosting)이 있다.
Bagging
Bagging(Bootstrap Aggregating) 은 여러 모델을 ‘병렬’로 학습시키는 기법이다.
Bootstrap (데이터 분할): 원본 데이터셋에서 복원 추출(중복 허용)을 통해 랜덤하게 여러 개의 서브 데이터셋을 생성한다.
각각의 데이터셋으로 동일한 알고리즘의 모델을 여러개 독립적으로 학습시킨다.
Aggregating (결과 종합): 각 모델의 예측 결과를 종합하여 최종 예측값을 결정.
결과적으로 모델의 분산을 줄이고 일반화 성능을 높이는 효과가 생긴다. 비유하자면 학생들이 혼자 시험을 풀고, 이후 다수결로 정답을 고르는 것이다. 각자 틀리는 문제는 다를 수 있지만, 함께 하면 정답률이 올라간다.
Boosting
배깅이 병렬의 성질을 가졌다면, 부스팅은 여러 모델을 ‘직렬(순차적)’로 연결하여 학습하는 기법이다.
첫 번째 모델이 전체 데이터를 학습하고 예측을 수행.
이때 예측이 틀린 데이터에 더 큰 가중치를 부여한다.
두 번째 모델은 앞선 모델이 틀린 데이터에 더 집중하여 학습을 진행.
이 과정을 순차적으로 반복하며 이전 모델의 약점을 계속해서 보완해 나간다.
앞선 모델의 실수를 다음 모델이 고쳐나가는 방식이므로 모델의 편향(Bias)을 줄이고 예측 정확도를 극대화하는 데 매우 효과적이다. 단, 순차적으로 학습해야 하므로 속도가 상대적으로 느리고 과적합에 빠질 위험이 있다.
3. Random Forest
Random Forest는 여러 개의 Decision Tree를 Bagging기법으로 학습시키는 모델이다. 또한 개별 트리들이 서로 너무 비슷해져 앙상블의 효과가 떨어지는 것을 막기 위해 ‘데이터’와 ‘특징(Feature)’에 대해 무작위성을 부여한다.
데이터 무작위성 (Bootstrap Sample): 원본 데이터셋에서 복원 추출을 통해 여러 개의 서브 데이터셋을 무작위로 만든다. (Row 단위의 무작위 추출)
특징 무작위성 (Feature Subset): 트리가 분기할 때, 모든 특징을 고려하는 것이 아니라 일부 특징만 무작위로 선택하여 그중에서 최적의 기준을 찾는다. (Column 단위의 무작위 추출)
만약 압도적으로 중요한 특징이 있다면, 모든 트리가 그 특징 위주로만 분기하여 똑같이 생긴 나무들만 만들어질 것이다. -> 특징 선택에 제한을 두면 다양하고 독립적인 형태의 트리들이 생성될 수 있다.
랜덤 포레스트의 학습과 예측은 다음과 같은 단계로 진행된다.
데이터를 여러 개의 데이터셋으로 분할(Bootstrap)한다.
각각의 데이터셋을 이용해 트리를 만든다. 이때 분기할 때마다 전체 특징(Feature) 중 일부를 무작위로 골라(Subset), 그 안에서 불순도를 가장 많이 줄이는 기준으로 분기한다.
1번과 2번의 과정을 반복하여, 서로 조금씩 다른 형태로 훈련된 여러개의 의사결정트리를 만든다.
각 트리는 Bootstrap 데이터와 선택된 Subset으로 의사결정트리를 만든다.
결과 집계 (Aggregation): 새로운 데이터가 들어오면 모든 트리가 각자 예측을 수행한다. 분류 문제라면 가장 많이 나온 결과를 다수결로 선택하고, 회귀 문제라면 모든 트리의 예측값을 평균(Mean) 내어 최종 예측값을 결정한다.
장점: 단일 의사결정나무의 치명적인 단점인 과적합 문제를 효과적으로 해결하며, 노이즈 데이터에 강하고 예측 성능이 매우 뛰어나다.
단점: 수많은 트리가 복합적으로 작용하므로, 의사결정나무처럼 “왜 이런 결과가 나왔는지” 직관적으로 해석하기가 어렵다.